package utils

import (
	"errors"
	"fmt"
	"os/exec"
	"sync"
)

type CmdRunner struct {
	lock   *sync.RWMutex
	cmdMap map[string]*exec.Cmd
}

func NewCmdRunner() *CmdRunner {
	rval := &CmdRunner{
		lock:   new(sync.RWMutex),
		cmdMap: make(map[string]*exec.Cmd),
	}
	return rval
}

func (this *CmdRunner) IsRunning(id string) bool {
	this.lock.RLock()
	defer this.lock.RUnlock()
	return this.cmdMap[id] != nil
}

func (this *CmdRunner) Start(id string, cmdstr string) error {
	this.lock.Lock()
	defer this.lock.Unlock()

	cmd := this.cmdMap[id]
	if cmd != nil {
		return errors.New(fmt.Sprintf("对应的ID:%s已经运行", id))
	}

	cmdr := GetExecShellCmd(cmdstr)
	err := cmdr.Start() //  ExecCmdNoWaitNoSettingIO(cmdstr)
	if err != nil {
		Log.Warnf("执行了[%s], 命令行:%s, 出现异常:%s", id, cmdstr, err.Error())
		return nil
	} else {
		this.cmdMap[id] = cmdr
		Log.Infof("执行了[%s], 命令行:%s", id, cmdstr)
		return nil
	}
}

func (this *CmdRunner) Stop(id string) error {
	this.lock.Lock()
	defer this.lock.Unlock()

	cmd := this.cmdMap[id]
	if cmd != nil {
		Log.Infof("停止[%s], PID:%d", id, cmd.Process.Pid)
		cmd.Process.Kill()
		delete(this.cmdMap, id)
	} else {
		return errors.New(fmt.Sprintf("对应的[%s],命令尚未运行", id))
	}
	return nil
}
